package com.topnav.mc.zzd;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.js.lib.result.Result;
import com.js.lib.utils.DateUtils;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.service.IDeviceService;
import com.topnav.mc.base.mc.McPage;
import com.topnav.mc.uitls.RedisUtil;
import com.topnav.mc.zzd.ZzdApiUrl;
import com.topnav.mc.zzd.ZzdHttpUtil;
import static com.topnav.mc.zzd.ZzdHttpUtil.ApiCallBack;

import com.topnav.mc.zzd.account.ZzdAccountUntil;
import com.topnav.mc.zzd.bean.UpdateCount;
import com.topnav.mc.zzd.bean.ZzdUserBean;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import java.net.URLEncoder;
import java.util.*;

/**
 * @Author: kenny
 * @Date: 2024/1/10 17:15
 */
@RestController
@CrossOrigin
@RequestMapping({"/test/zzd/user","/zzd/user"})
@Slf4j
public class ZzdUserController {
    @Autowired
    private ZzdApiUrl zzdApiUrl;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    ZzdAccountUntil zzdAccountUntil;

    /**
     * 分页查询用户
     * @param page
     * @return
     */
    @PostMapping({"/query/page"})
    @ResponseBody
    public DeferredResult<Result> queryPage(@RequestBody McPage<ZzdUserBean> page){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("网络超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        Map<String,Object> map = new HashMap<>();
        map.put("limit",page.getPage().getSize());
        map.put("page",page.getPage().getCurrent()-1);
        if (page.getWhere()!=null){
            if (page.getWhere().getUserStatus() != null){map.put("user_status",page.getWhere().getUserStatus());}
            if (page.getWhere().getUserOnline() != null){map.put("user_online",page.getWhere().getUserOnline());}
            if (page.getWhere().getUserName()!= null){map.put("user_name",page.getWhere().getUserName());}
            if (page.getWhere().getUserAccount()!= null){map.put("user_account",page.getWhere().getUserAccount());}
            if (page.getWhere().getOrderBy() != null){map.put("order_by",page.getWhere().getOrderBy());}
            if (page.getWhere().getOrderType() != null){map.put("order_type",page.getWhere().getOrderType());}
            if (page.getWhere().getGroupId() != null){
                if (page.getWhere().getGroupId().indexOf("-") > -1){
                    map.put("group_id",page.getWhere().getGroupId().split("-")[1]);
                }else{
                    map.put("group_id",page.getWhere().getGroupId());
                }
            }
        }
        String url=zzdApiUrl.queryUser(map);
        ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {
                Page<ZzdUserBean> resultPage = new  Page();
                List<ZzdUserBean> records = new ArrayList<>();
                JSONObject json = JSONObject.parseObject(resultJson);
                JSONObject data = json.getJSONObject("data");
                resultPage.setTotal(data.getInteger("total"));
                JSONArray users = (JSONArray)data.get("users");
                for(int i=0;i<users.size();i++){
                    JSONObject jd = (JSONObject)users.get(i);
                    ZzdUserBean bean = new ZzdUserBean();
                    bean.setUserId(jd.getString("user_id"));
                    bean.setUserName(jd.getString("user_name"));
                    bean.setUserAccount(jd.getString("user_account"));
                    bean.setClientType(jd.getString("client_type"));

                    bean.setDefaultGroup(jd.getString("default_group"));
                    bean.setDefaultGroupName(jd.getString("default_group_name"));
                    bean.setGroupIds(jd.getString("group_ids"));
                    bean.setGroupId(jd.getString("group_id"));
                    bean.setUserStatus(jd.getInteger("user_status"));
                    bean.setUserOnline(jd.getInteger("user_online"));
                    bean.setGroupNames(jd.getString("group_names"));
                    bean.setBillId(jd.getString("bill_id"));
                    bean.setPartAccount(jd.getString("part_account"));
                    records.add(bean);
                }

                //根据userAccount查本地对应的 device
                List<String> talkAccounts = new ArrayList<>();
                for(ZzdUserBean bean : records){
                    talkAccounts.add(bean.getUserAccount());
                }
                if (talkAccounts.size() >0){
                    LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<Device>().in(Device::getTalkAccount,talkAccounts);
                    List<Device> devices = deviceService.list(wrapper);
                    for(ZzdUserBean bean : records){
                        for(Device device : devices){
                            if (bean.getUserAccount().equals(device.getTalkAccount())){
                                bean.setDeviceCode(device.getCode());
                                bean.setDeviceId(device.getId());
                                bean.setDeviceName(device.getName());
                                break;
                            }
                        }
                    }

                }

                resultPage.setRecords(records);
                result.setResult(Result.ok(resultPage));
            }
        },new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        });
        return result;
    }

    /**
     * 新增帐号
     * @param params List<ZzdUserBean></>
     * @return
     */
    @PostMapping({"/add"})
    @ResponseBody
    public DeferredResult<Result> addUser(@RequestBody List<ZzdUserBean> params){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(10000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("网络超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        if (CollectionUtils.isEmpty(params)){
            result.setResult(Result.error("参数不全"));
        }
        String random = (String) RedisUtil.get(ZzdConstant.ZZD_RANDOM_KEY);
        if (random == null){
            result.setResult(Result.error("第三方系统未登录"));
        }
        //有效订单号
        Object obj=RedisUtil.get(ZzdConstant.ZZD_VALIDBILL_IDS + zzdAccountUntil.getZzdAccount().getAccount());
        Integer billId=1;
        if (obj != null){
            billId = Integer.valueOf(obj.toString().split(",")[0].toString());
        }
        UpdateCount updateCount = new UpdateCount();
        updateCount.setCurr(0);
        updateCount.setTotal(params.size());
        while (updateCount.getCurr() < updateCount.getTotal()){
             try{
                Map<String,Object> map = new HashMap<>();
                ZzdUserBean bean = params.get(updateCount.getCurr());
                map.put("user_account",bean.getUserAccount());
                map.put("pwd",ZzdHttpUtil.sha1("111111"));
                map.put("user_name", URLEncoder.encode(bean.getUserName()));
                map.put("proxy_account",zzdAccountUntil.getZzdAccount().getAccount());
                map.put("proxy_pwd",ZzdHttpUtil.hmacSha1(random, ZzdHttpUtil.sha1(zzdAccountUntil.getZzdAccount().getPassword())));
                map.put("bill_id",billId);
                map.put("bill_type",1);
                map.put("clientType",3);
                map.put("desc",URLEncoder.encode(bean.getUserName()));
                map.put("default_group",bean.getGroupId());
                String url=zzdApiUrl.newUser(map);
                ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
                    @Override
                    public void onResult(String resultJson) {//成功
                        log.debug(resultJson);
                        JSONObject json = JSONObject.parseObject(resultJson);
                        if (json.getInteger("code") != null) {
                            if (json.getInteger("code") == 0) {
                                //JSONObject data = json.getJSONObject("data").getString("id");

                                Device device = deviceService.getById(bean.getDeviceId());
                                device.setTalkAccount(bean.getUserAccount());
                                device.setTalkId(json.getJSONObject("data").getString("id"));
                                deviceService.updateById(device);
                                updateCount.setSuccessCount(updateCount.getSuccessCount() + 1);
                            }else{
                                updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                                updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                                //updateCount.getMsgs().put(bean.getUserAccount(),json.getString("msg"));
                            }
                        }else{
                            updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                        }
                        updateCount.setCurr(updateCount.getCurr()+1);
                        log.debug(resultJson);
                        if (updateCount.getCurr() == updateCount.getTotal()){
                            result.setResult(Result.ok(updateCount));
                        }
                    }
                },  new ZzdHttpUtil.ApiCallBack() {
                    @Override
                    public void onResult(String resultJson) {//失败
                        //{"code":1,"data":{},"msg":"accountExist"}
                        log.error(resultJson);
                        JSONObject json = JSONObject.parseObject(resultJson);
                        if (json.get("msg") != null){
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                        }else{
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                            //updateCount.getMsgs().put(bean.getUserAccount(),resultJson);
                        }
                        updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                        updateCount.setCurr(updateCount.getCurr()+1);
                        if (updateCount.getCurr() >= updateCount.getTotal()){
                            result.setResult(Result.ok(updateCount));
                        }
                    }
                });
            }catch (Exception e){
                log.error(e.toString());
                updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                //updateCount.getMsgs().put("error",e.toString());
                 updateCount.getMsgs().append("error").append(":").append(e.toString()).append(";");
                updateCount.setCurr(updateCount.getCurr()+1);
                if (updateCount.getCurr() == updateCount.getTotal()){
                    result.setResult(Result.ok(updateCount));
                }
            }
            //result.setResult(Result.ok(updateCount));
         }
        return result;
    }

    /**
     * 删除帐号
     * @param params 多个以,号分隔
     * @return
     */
    @PostMapping({"/delete"})
    @ResponseBody
    public DeferredResult<Result> deleteUser(@RequestBody List<ZzdUserBean> params){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("网络超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        if (CollectionUtils.isEmpty(params)){
            result.setResult(Result.error("参数不全"));
        }

        UpdateCount updateCount = new UpdateCount();
        updateCount.setCurr(0);
        updateCount.setTotal(params.size());
        while (updateCount.getCurr() < updateCount.getTotal()){
            ZzdUserBean bean = params.get(updateCount.getCurr());
            try {
                Map<String,Object> map = new HashMap<>();
                map.put("user_ids",bean.getUserId());
                String url=zzdApiUrl.deleteUser(map);
                ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
                    @Override
                    public void onResult(String resultJson) {
                        log.debug(resultJson);

                        JSONObject json = JSONObject.parseObject(resultJson);
                        if (json.getInteger("code") != null) {
                            if (json.getInteger("code") == 0) {
                                QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
                                queryWrapper.eq("talk_id",bean.getUserId());
                                Device device = deviceService.getOne(queryWrapper,false);

                                UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
                                updateWrapper.set("talk_account",null);
                                updateWrapper.set("talk_id",null);
                                updateWrapper.eq("talk_id",bean.getUserId());
                                deviceService.update(updateWrapper);

                                if (device != null){
                                    device.setTalkId(null);
                                    device.setTalkAccount(null);
                                    deviceService.saveToCache(device);
                                }
                                updateCount.setSuccessCount(updateCount.getSuccessCount() + 1);
                            }else{
                                updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                                updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                            }
                        }else{
                            updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                        }
                        updateCount.setCurr(updateCount.getCurr()+1);
                        if (updateCount.getCurr() >= updateCount.getTotal()){
                            result.setResult(Result.ok(updateCount));
                        }
                        //result.setResult(ZzdHttpUtil.genResult(resultJson));
                    }
                },new ZzdHttpUtil.ApiCallBack() {
                    @Override
                    public void onResult(String resultJson) {
                        //{"code":1,"data":{},"msg":"accountExist"}
                        log.error(resultJson);
                        JSONObject json = JSONObject.parseObject(resultJson);
                        if (json.get("msg") != null){
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                        }else{
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                        }
                        updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                        updateCount.setCurr(updateCount.getCurr()+1);
                        if (updateCount.getCurr() >= updateCount.getTotal()){
                            result.setResult(Result.ok(updateCount));
                        }
                    }
                });
            }catch (Exception e){
                log.error(e.toString());
                updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(e.toString()).append(";");
                updateCount.setCurr(updateCount.getCurr()+1);
                if (updateCount.getCurr() >= updateCount.getTotal()){
                    result.setResult(Result.ok(updateCount));
                }
            }

        }


        return result;
    }

    @PostMapping({"/aynctest"})
    @ResponseBody
    public DeferredResult<Result> aynctest(){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(10000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("网络超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        UpdateCount updateCount = new UpdateCount();
        int timer = 0;
        while (updateCount.getSuccessCount() < 10){
            timer ++;
            log.info("{}:",timer);
            Map<String,Object> map = new HashMap<>();
            map.put("limit",1);
            map.put("page",0);
            String url=zzdApiUrl.queryUser(map);
            ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//成功
                    updateCount.setSuccessCount(updateCount.getSuccessCount() + 1);
                    log.info("成功,{}次", updateCount.getSuccessCount());
                    if (updateCount.getSuccessCount() ==10){
                        result.setResult(Result.ok(updateCount));
                    }
                }
            },  new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//失败
                    updateCount.setFailedCount(updateCount.getFailedCount() + 1);
                    updateCount.setSuccessCount(updateCount.getSuccessCount() + 1);
                    log.info("失败,{}次", updateCount.getFailedCount());
                    if (updateCount.getSuccessCount() ==10){
                        result.setResult(Result.ok(updateCount));
                    }
                }
            });
        }
        return result;
    };

}
